﻿using System;
using System.Collections;
using System.Data;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace VeryCodes.Common
{
    /// <summary>
    /// 该类用于封装对于控件的常用操作,如获取控件数据，设置控件数据，绑定数据源等。
    /// </summary>
    public class ControlHelper
    {
        /// <summary>
        /// 无参构造函数
        /// </summary>
        public ControlHelper()
        {

        }

        /// <summary>
        /// 根据指定的控件ID获取相应的控件，主要用于找到GridView里的控件
        /// </summary>
        /// <param name="Ctl">父控件</param>
        /// <param name="ControlID">指定控件ID</param>
        /// <returns>指定控件</returns>
        public Control GetChildControl(Control Ctl, string ControlID)
        {
            foreach (Control Cctl in Ctl.Controls)
            {
                if (Cctl.ID == ControlID)
                {
                    return Cctl;
                }
                else
                {
                    Control Ctl2 = GetChildControl(Cctl, ControlID);
                    if (Ctl2 != null)
                    {
                        return Ctl2;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取控件的文本值，主要包括：
        /// 1. TextBox.Text
        /// 2. HiddenField.Value
        /// 3. DropDownList.SelectedValue
        /// 4. CheckBox.Text
        /// 5. Label.Text
        /// </summary>
        /// <param name="Ctl">父控件</param>
        /// <param name="ControlID">指定控件ID</param>
        /// <returns>指定控件的文本值</returns>
        public string GetControlValue(Control Ctl, string ControlID)
        {
            string ReturnValue = "";
            Control Ctrl = GetChildControl(Ctl, ControlID);
            if (Ctrl != null)
            {
                if (Ctrl is TextBox)
                    ReturnValue = (Ctrl as TextBox).Text;
                else if (Ctrl is HiddenField)
                    ReturnValue = (Ctrl as HiddenField).Value;
                else if (Ctrl is DropDownList)
                    ReturnValue = (Ctrl as DropDownList).SelectedValue;
                else if (Ctrl is CheckBox)
                    ReturnValue = (Ctrl as CheckBox).Text;
                else if (Ctrl is Label)
                    ReturnValue = (Ctrl as Label).Text;
                else
                    ReturnValue = GetControlValue((UserControl)Ctrl, "Text");
            }

            return ReturnValue;
        }

        /// <summary>
        /// 获取CheckBox或Radio的Check值
        /// </summary>
        /// <param name="Ctl">父控件</param>
        /// <param name="ControlID">指定控件ID</param>
        /// <returns>指定控件的值</returns>
        public bool GetBoolValue(Control Ctl, string ControlID)
        {
            bool ReturnValue = false;
            Control Ctrl = GetChildControl(Ctl, ControlID);
            if (Ctrl != null)
            {
                if (Ctrl is CheckBox)
                    ReturnValue = (Ctrl as CheckBox).Checked;
                else if (Ctrl is RadioButton)
                    ReturnValue = (Ctrl as RadioButton).Checked;
            }

            return ReturnValue;
        }

        /// <summary>
        /// 获取DropDown的选中数据
        /// </summary>
        /// <param name="Ctl">父控件</param>
        /// <param name="ControlID">指定控件ID</param>
        /// <returns>指定DropDownList控件的选中数据</returns>
        public ListItem GetDropDownValue(Control Ctl, string ControlID)
        {
            System.Web.UI.WebControls.ListItem ReturnValue = new ListItem();
            Control Ctrl = GetChildControl(Ctl, ControlID);
            if (Ctrl != null)
            {
                ReturnValue = (Ctrl as DropDownList).SelectedItem;
            }
            return ReturnValue;
        }

        /// <summary>
        /// 根据控件、属性名称、属性值，设置控件的属性值
        /// 如果发生异常，则设置无效
        /// </summary>
        /// <param name="Control">要设置的控件</param>
        /// <param name="PropertyName">属性名称</param>
        /// <param name="PropertyValue">属性值</param>
        public void SetControlValue(UserControl Control, string PropertyName, object PropertyValue)
        {
            System.Type ControlType;
            System.Reflection.PropertyInfo objProperty;
            ControlType = Control.GetType();

            try
            {
                objProperty = ControlType.GetProperty(PropertyName);
                objProperty.SetValue(Control, PropertyValue, null);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 根据输入的控件、属性名称，获得控件的属性值
        /// 如果发生异常，返回空字符串
        /// </summary>
        /// <param name="Control">要获取的控件</param>
        /// <param name="PropertyName">属性名称</param>
        /// <returns>属性值</returns>
        public string GetControlValue(UserControl Control, string PropertyName)
        {
            System.Type ControlType;
            System.Reflection.PropertyInfo ObjProperty;
            ControlType = Control.GetType();

            Object ObjReturn = null;
            try
            {
                ObjProperty = ControlType.GetProperty(PropertyName);
                ObjReturn = ObjProperty.GetValue(Control, null);
            }
            catch
            {

            }

            if (ObjReturn == null)
                return "";
            else
                return ObjReturn.ToString();
        }

        /// <summary>
        /// 使用指定的参数调用用户控件中的方法或函数
        /// </summary>
        /// <param name="Control">用户控件</param>
        /// <param name="MethodName">方法名称</param>
        /// <param name="Parameters">方法参数</param>
        public void InvokeControlMethod(UserControl Control, string MethodName, params string[] Parameters)
        {
            System.Type ControlType;
            System.Reflection.MethodInfo objMethod;
            ControlType = Control.GetType();
            objMethod = ControlType.GetMethod(MethodName);
            objMethod.Invoke(Control, Parameters);
        }

        /// <summary>
        /// 绑定的控件类型
        /// DropDown, RadioButtonList, CheckBoxList
        /// </summary>
        public enum EnumControlType
        {
            /// <summary>
            /// DropDownList
            /// </summary>
            DropDown,

            /// <summary>
            /// RadioButtonList
            /// </summary>
            RadioButtonList,

            /// <summary>
            /// CheckBoxList
            /// </summary>
            CheckBoxList
        }

        #region 公共方法

        /// <summary>
        /// 绑定枚举类型到控件，用于DropDownList、RadioButtonList、CheckBoxList
        /// </summary>
        /// <param name="obj">Object要绑定的控件</param>
        /// <param name="enumType">枚举类型</param>
        /// <param name="HeaderText">用于DropDownList,其它控件为空字符串，为列表项提供标题或默认选中项文本内容，如：请选择</param>
        public static void BindDataSource(object obj, Type enumType, string HeaderText)
        {
            if (typeof(DropDownList) == obj.GetType() || obj.GetType().IsSubclassOf(typeof(DropDownList)))
            {
                BindDropDownDataTable(obj, enumType, HeaderText);
            }
            else if (typeof(CheckBoxList) == obj.GetType() || obj.GetType().IsSubclassOf(typeof(CheckBoxList)))
            {
                BindCheckBoxListDataTable(obj, enumType);
            }
            else if (typeof(RadioButtonList) == obj.GetType() || obj.GetType().IsSubclassOf(typeof(RadioButtonList)))
            {
                BindRadioButtonListDataTable(obj, enumType);
            }
        }

        /// <summary>
        /// 绑定DataTable数据表到控件
        /// </summary>
        /// <param name="obj">Object 要绑定的控件</param>
        /// <param name="dt">要绑定的DataTable</param>
        /// <param name="ValueField">为列表项提供文本内容的数据源字段</param>
        /// <param name="TextField">为列表项提供值的数据源字段</param>
        /// <param name="HeaderText">用于DropDownList，为列表项提供标题或默认选中项文本内容，如：请选择，可以为空</param>
        public static void BindDataSource(object obj, DataTable dt, string ValueField, string TextField, string HeaderText)
        {
            if (typeof(DropDownList) == obj.GetType() || obj.GetType().IsSubclassOf(typeof(DropDownList)))
            {
                BindDropDownDataTable(obj, dt, ValueField, TextField, HeaderText);
            }
            else if (typeof(CheckBoxList) == obj.GetType() || obj.GetType().IsSubclassOf(typeof(CheckBoxList)))
            {
                BindCheckBoxListDataTable(obj, dt, ValueField, TextField);
            }
            else if (typeof(RadioButtonList) == obj.GetType() || obj.GetType().IsSubclassOf(typeof(RadioButtonList)))
            {
                BindRadioButtonListDataTable(obj, dt, ValueField, TextField);
            }
        }
        #endregion 公共方法

        #region 私有方法

        /// <summary>
        /// 绑定枚举类型到RadioButtonList控件
        /// </summary>
        /// <param name="obj">Object要绑定的控件</param>
        /// <param name="enumType">枚举类型</param>
        private static void BindRadioButtonListDataTable(object obj, Type enumType)
        {
            RadioButtonList rdol = (obj as RadioButtonList);
            DataTable dt = EnumHelper.GetEnumList(enumType);
            rdol.DataSource = dt;
            rdol.DataValueField = "Value";
            rdol.DataTextField = "Text";
            rdol.DataBind();
            dt.Dispose();
        }

        /// <summary>
        /// 绑定枚举类型到CheckBoxList控件
        /// </summary>
        /// <param name="obj">Object要绑定的控件</param>
        /// <param name="enumType">枚举类型</param>
        private static void BindCheckBoxListDataTable(object obj, Type enumType)
        {
            CheckBoxList rdol = (obj as CheckBoxList);
            DataTable dt = EnumHelper.GetEnumList(enumType);
            rdol.DataSource = dt;
            rdol.DataValueField = "Value";
            rdol.DataTextField = "Text";
            rdol.DataBind();
            dt.Dispose();
        }

        /// <summary>
        /// 绑定枚举类型到DropDownList控件
        /// </summary>
        /// <param name="obj">Object要绑定的控件</param>
        /// <param name="enumType">枚举类型</param>
        /// <param name="HeaderText"></param>
        private static void BindDropDownDataTable(object obj, Type enumType, string HeaderText)
        {
            DataTable dt = EnumHelper.GetEnumList(enumType);
            BindDataSource(obj, dt, "Value", "Text", HeaderText);
        }

        /// <summary>
        /// 绑定DataTable数据表到RadioButtonList控件
        /// </summary>
        /// <param name="obj">Object 要绑定的控件</param>
        /// <param name="dt">要绑定的DataTable</param>
        /// <param name="ValueField">为列表项提供文本内容的数据源字段</param>
        /// <param name="TextField">为列表项提供值的数据源字段</param>
        private static void BindRadioButtonListDataTable(object obj, DataTable dt, string ValueField, string TextField)
        {
            RadioButtonList drp = (obj as RadioButtonList);
            drp.DataSource = dt;
            drp.DataValueField = ValueField;
            drp.DataTextField = TextField;
            drp.DataBind();
            dt.Dispose();
        }

        /// <summary>
        /// 绑定DataTable数据表到CheckBoxList控件
        /// </summary>
        /// <param name="obj">Object 要绑定的控件</param>
        /// <param name="dt">要绑定的DataTable</param>
        /// <param name="ValueField">为列表项提供文本内容的数据源字段</param>
        /// <param name="TextField">为列表项提供值的数据源字段</param>
        private static void BindCheckBoxListDataTable(object obj, DataTable dt, string ValueField, string TextField)
        {
           
            CheckBoxList drp = (obj as CheckBoxList);
            
            drp.DataSource = dt;
            drp.DataValueField = ValueField;
            drp.DataTextField = TextField;
            drp.DataBind();
            dt.Dispose();
        }

        /// <summary>
        /// 绑定DataTable数据表到DropDownList控件
        /// </summary>
        /// <param name="obj">Object 要绑定的控件</param>
        /// <param name="dt">要绑定的DataTable</param>
        /// <param name="ValueField">为列表项提供文本内容的数据源字段</param>
        /// <param name="TextField">为列表项提供值的数据源字段</param>
        /// <param name="HeaderText">为列表项提供标题或默认选中项文本内容，如：请选择，可以为空</param>
        private static void BindDropDownDataTable(object obj, DataTable dt, string ValueField, string TextField, string HeaderText)
        {
            DropDownList drp = (obj as DropDownList);
            if (HeaderText.Trim() != "")
            {
                DataRow dr = dt.NewRow();
                dr[ValueField] = "";
                dr[TextField] = HeaderText;
                dt.Rows.InsertAt(dr, 0);
            }
            drp.DataSource = dt;
            drp.DataValueField = ValueField;
            drp.DataTextField = TextField;
            drp.DataBind();
            dt.Dispose();
        }

        #endregion 私有方法
    }
}
